/*****************************************************************************************
   
   Copyright (c) Microsoft Corporation. All rights reserved.

   Use of this code sample is subject to the terms of the Microsoft
   Permissive License, a copy of which should always be distributed with
   this file.  You can also access a copy of this license agreement at:
   http://www.microsoft.com/resources/sharedsource/licensingbasics/permissivelicense.mspx

 ****************************************************************************************/

using System;

namespace GrooveWebServicesV12Helpers.Files
{
	/// <summary>
	/// Abstract base class for files and folders in a Groove Files tool.
	/// </summary>
	public abstract class FileFolderBase : GrooveWebServicesV12HelpersBase
	{
		protected GrooveWebServicesV12Helpers.Files.FilesTool m_FilesTool;
		protected GrooveWebServicesV12Helpers.Files.Folder m_ParentFolder;
		
		protected GrooveFilesWebService.FileDescriptor m_FileDescriptor;

		public FileFolderBase(GrooveWebServicesV12Helpers.Files.FilesTool i_FilesTool, GrooveFilesWebService.FileDescriptor i_FileDescriptor) :
			this(i_FilesTool, null, i_FileDescriptor)
		{
		}

		public FileFolderBase(GrooveWebServicesV12Helpers.Files.FilesTool i_FilesTool, GrooveWebServicesV12Helpers.Files.Folder i_ParentFolder, GrooveFilesWebService.FileDescriptor i_FileDescriptor)
			: base(i_FileDescriptor.Name, i_FileDescriptor.URI, i_FilesTool.IdentityURL, i_FilesTool.Context)
		{
			m_FilesTool = i_FilesTool;
			m_ParentFolder = i_ParentFolder;
			m_FileDescriptor = i_FileDescriptor;
		}

		/// <summary>
		/// The FilesTool which contains this File or Folder
		/// </summary>
		public GrooveWebServicesV12Helpers.Files.FilesTool FilesTool
		{
			get
			{
				return m_FilesTool;
			}
		}

		/// <summary>
		/// The parent folder which contains this File or Folder
		/// </summary>
		public GrooveWebServicesV12Helpers.Files.Folder ParentFolder
		{
			get
			{
				return m_ParentFolder;
			}
		}

		/// <summary>
		/// The ID of this File or Folder
		/// </summary>
		public string ID
		{
			get
			{
				return m_FileDescriptor.ID;
			}
		}

		/// <summary>
		/// IdentityURL of the Groove user who created this File or Folder
		/// </summary>
		public string CreatedBy
		{
			get
			{
				return m_FileDescriptor.CreatedBy;
			}
		}

		/// <summary>
		/// IdentityURL of the Groove user who last modified this File or Folder
		/// </summary>
		public string ModifiedBy
		{
			get
			{
				return m_FileDescriptor.ModifiedBy;
			}
		}

		/// <summary>
		/// DateTime this File or Folder was created
		/// </summary>
		public System.DateTime Created
		{
			get
			{
				return m_FileDescriptor.Created;
			}
		}

		/// <summary>
		/// DateTime this File or Folder was last modified
		/// </summary>
		public System.DateTime Modified
		{
			get
			{
				return m_FileDescriptor.Modified;
			}
		}

		/// <summary>
		/// ID of the parent folder which contains this File or Folder
		/// </summary>
		public string ParentFolderID
		{
			get
			{
				return m_FileDescriptor.FolderID;
			}
		}

		/// <summary>
		/// True if this file is unread
		/// </summary>
		public bool Unread
		{
			get
			{
				return m_FileDescriptor.Unread;
			}
		}

		/// <summary>
		/// Name of this file or folder
		/// </summary>
		public override string Name
		{
			set
			{
				//  Do nothing if value already assigned
				if (m_FileDescriptor.Name == value)
					return;

				string OldValue = m_FileDescriptor.Name;

				try
				{
					//  Update local instance
					m_FileDescriptor.Name = value;

					//  Update data
					int_Update(null);
				}
				catch (System.Exception Exception)
				{
					//  Revert local instance
					m_FileDescriptor.Name = OldValue;

					throw Exception;
				}
			}
		}

		/// <summary>
		/// DisplayName of this file or folder
		/// </summary>
		public string DisplayName
		{
			get
			{
				return m_FileDescriptor.DisplayName;
			}
			set
			{
				//  Do nothing if value already assigned
				if (m_FileDescriptor.DisplayName == value)
					return;

				string OldValue = m_FileDescriptor.DisplayName;

				try
				{
					//  Update local instance
					m_FileDescriptor.DisplayName = value;

					//  Update data
					int_Update(null);
				}
				catch (System.Exception Exception)
				{
					//  Revert local instance
					m_FileDescriptor.DisplayName = OldValue;

					throw Exception;
				}
			}
		}

		/// <summary>
		/// Type: "File" or "Folder"
		/// </summary>
		public string Type
		{
			get
			{
				return m_FileDescriptor.Type;
			}
		}

		/// <summary>
		/// Download state: 1 (local), 2 (remote), 3 (in process of downloading), or 4 (download attempted, but encountered an error).
		/// </summary>
		public int DownloadState
		{
			get
			{
				return m_FileDescriptor.DownloadState;
			}
		}

		/// <summary>
		/// Mark this file as "read"
		/// </summary>
		public void MarkRead()
		{
			//  Get initialized reference to web service
			GrooveFilesWebService.GrooveFilesBase64 FilesWebService = GrooveWebServicesV12Helpers.Files.FilesTool.CreateInitializedFilesWebService
				(
				m_IdentityURL,
				m_FileDescriptor.URI,
				Context
				);

			System.DateTime BeginDateTime = System.DateTime.Now;

			//  Ask service to delete Files entry
			FilesWebService.UpdateUnreadMark(false);

			if (GrooveWebServicesV12Helpers.Context.TraceEnabled)
			{
				System.TimeSpan TimeSpan = System.DateTime.Now.Subtract(BeginDateTime);
				System.Diagnostics.Debug.WriteLine("FilesWebService::UpdateUnreadMark, " + TimeSpan.TotalMilliseconds + " ms");
			}
		}

		/// <summary>
		/// Mark this file as "unread"
		/// </summary>
		public void MarkUnread()
		{
			//  Get initialized reference to web service
			GrooveFilesWebService.GrooveFilesBase64 FilesWebService = GrooveWebServicesV12Helpers.Files.FilesTool.CreateInitializedFilesWebService
				(
				m_IdentityURL,
				m_FileDescriptor.URI,
				Context
				);

			System.DateTime BeginDateTime = System.DateTime.Now;

			//  Ask service to delete Files entry
			FilesWebService.UpdateUnreadMark(true);

			if (GrooveWebServicesV12Helpers.Context.TraceEnabled)
			{
				System.TimeSpan TimeSpan = System.DateTime.Now.Subtract(BeginDateTime);
				System.Diagnostics.Debug.WriteLine("FilesWebService::UpdateUnreadMark, " + TimeSpan.TotalMilliseconds + " ms");
			}
		}

		/// <summary>
		/// Update this file
		/// </summary>
		/// <param name="i_Name">New filename</param>
		/// <param name="i_DisplayName">New displayname</param>
		/// <param name="i_FileContents">Byte array with the new file contents</param>
		public void Update(string i_Name, string i_DisplayName, System.Byte[] i_FileContents)
		{
			string Name_OldValue = i_Name;
			string DisplayName_OldValue = i_DisplayName;

			try
			{
				//  Update local instance
				m_FileDescriptor.Name = i_Name;
				m_FileDescriptor.DisplayName = i_DisplayName;

				//  Update data
				int_Update(i_FileContents);
			}
			catch (System.Exception Exception)
			{
				//  Revert local instance
				m_FileDescriptor.Name = Name_OldValue;
				m_FileDescriptor.DisplayName = DisplayName_OldValue;

				throw Exception;
			}
		}

		private void int_Update(System.Byte[] i_FileContents)
		{
			//  Get initialized reference to web service
			GrooveFilesWebService.GrooveFilesBase64 FilesWebService = GrooveWebServicesV12Helpers.Files.FilesTool.CreateInitializedFilesWebService
				(
				m_IdentityURL,
				this.URI,
				Context
				);

			System.DateTime BeginDateTime = System.DateTime.Now;

			//  Ask service to update file descriptor
			FilesWebService.UpdateFile(m_FileDescriptor, i_FileContents);

			if (GrooveWebServicesV12Helpers.Context.TraceEnabled)
			{
				System.TimeSpan TimeSpan = System.DateTime.Now.Subtract(BeginDateTime);
				System.Diagnostics.Debug.WriteLine("FilesWebService::UpdateFile, " + TimeSpan.TotalMilliseconds + " ms");
			}
		}

		/// <summary>
		/// Export to a local folder, including subfolders recursively, overwriting existing files if they exist already.
		/// </summary>
		/// <param name="i_TargetFolderPath">Path of the local folder</param>
		public void Export(string i_TargetFolderPath)
		{
			int_Export
				(
				i_TargetFolderPath,
				true,				//  Recursive
				true				//  OverwriteExisting
				);
		}

		/// <summary>
		/// Export to a local folder, overwriting existing files if they exist already.
		/// </summary>
		/// <param name="i_TargetFolderPath">Path of the local folder</param>
		/// <param name="i_Recursive">True to include subfolders recursively</param>
		public void Export(string i_TargetFolderPath, bool i_Recursive)
		{
			int_Export
				(
				i_TargetFolderPath,
				i_Recursive,
				true				//  OverwriteExisting
				);
		}

		/// <summary>
		/// Export to a local folder.
		/// </summary>
		/// <param name="i_TargetFolderPath">Path of the local folder</param>
		/// <param name="i_Recursive">True to include subfolders recursively</param>
		/// <param name="i_OverwriteExisting">True to overwrite existing files if they exist already</param>
		public void Export(string i_TargetFolderPath, bool i_Recursive, bool i_OverwriteExisting)
		{
			int_Export
				(
				i_TargetFolderPath,
				i_Recursive,
				i_OverwriteExisting
				);
		}

		private void int_Export(string i_TargetFolderPath, bool i_Recursive, bool i_OverwriteExisting)
		{
			if (!System.IO.Directory.Exists(i_TargetFolderPath))
				throw new System.ArgumentException("Specified path is not valid!");

			//  Get initialized reference to web service
			GrooveFilesWebService.GrooveFilesBase64 FilesWebService = GrooveWebServicesV12Helpers.Files.FilesTool.CreateInitializedFilesWebService
				(
				m_IdentityURL,
				this.URI,
				Context
				);

			System.DateTime BeginDateTime = System.DateTime.Now;

			//  Ask service to export
			FilesWebService.Export
				(
				i_TargetFolderPath,
				i_Recursive,
				i_OverwriteExisting
				);

			if (GrooveWebServicesV12Helpers.Context.TraceEnabled)
			{
				System.TimeSpan TimeSpan = System.DateTime.Now.Subtract(BeginDateTime);
				System.Diagnostics.Debug.WriteLine("FilesWebService::Export, " + TimeSpan.TotalMilliseconds + " ms");
			}
		}

		#region GrooveWebServicesV12Helpers.Base Implementation

		public override string BindableURL
		{
			get
			{
				if (System.String.IsNullOrEmpty(m_BindableURL))
					m_BindableURL = m_FilesTool.BindableURL + "/" + this.ID;

				return m_BindableURL;
			}
		}

		#endregion
	}
}
